﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;
using cludg.Infrastructure.DI;
using cludg.Infrastructure.Core.Logging;
using nsadv.Statistic.Web.Bootstrappers;
using nsadv.Statistic.Web.Notifications.Application;

namespace nsadv.Statistic.Web
{
	public class BaseApplication<TInjections> : System.Web.HttpApplication
		where TInjections : BaseInjectionConfiguration, new()
	{
		protected IDIContainer Container;

		protected ILogger Logger
		{
			get
			{
				var container = Application["DIContainer"] as IDIContainer;
				return container != null ? container.Resolve<ILogger>() : null;
			}
		}

		internal IApplicationNotificationSource NotificationSource
		{
			get
			{
				var container = Application["DIContainer"] as IDIContainer;
				return container != null ? container.Resolve<IApplicationNotificationSource>() : null;				
			}
		}

		private void ExecuteBootstrappers()
		{
			foreach (var bootstrapper in Container.ResolveAll<IBootstrapper>().OrderBy(x => x.Priority))
				bootstrapper.Execute();
		}

		protected virtual void Application_Start()
		{			
			AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true);

			AreaRegistration.RegisterAllAreas();

			Container = (new TInjections()).CreateContainer(this);
			this.Application["DIContainer"] = Container;

			Logger.Info("Application start");

			ExecuteBootstrappers();

			if (NotificationSource != null)
				NotificationSource.FireApplicationStart(Application);
		}

		protected virtual void Application_Error()
		{
			Exception error = Server.GetLastError().GetBaseException();
			Logger.Error("Application error", error);

			if (NotificationSource != null)
				NotificationSource.FireApplicationError(Application, error);
		}

		protected virtual void Application_End()
		{
			Logger.Info("Application end");

			if (NotificationSource != null)
				NotificationSource.FireApplicationEnd(Application);
		}

		protected virtual void Session_Start()
		{
			Logger.Info("ASP session start");

			if (NotificationSource != null)
				NotificationSource.FireSessionStart(Application, Session);		
		}


		protected virtual void Session_End()
		{
			Logger.Info("ASP session end");

			if (NotificationSource != null)
				NotificationSource.FireSessionEnd(Application, Session);		
		}
	}
}
